using System;
using System.Collections.Generic;
using System.Text;

namespace BAFHTTPD
{
    public class ResponseBuilder
    {
        public int ResponseCode = 200;
        public byte[] Content;
        public string ContentEncoding = "iso-8859-1";
        public string ContentType = "text/html";
        public Dictionary<string, string> Headers = new Dictionary<string,string>();

        public ResponseBuilder()
        {
        }

        public ResponseBuilder(int ResponseCode)
        {
            this.ResponseCode = ResponseCode;
        }

        public ResponseBuilder(int ResponseCode, byte[] Content)
        {
            this.ResponseCode = ResponseCode;
            this.Content = Content;
        }

        public ResponseBuilder(int ResponseCode, string Content)
        {
            this.ResponseCode = ResponseCode;
            this.Content = GetEncoder(ContentEncoding).GetBytes(Content);
        }

        public ResponseBuilder(int ResponseCode, byte[] Content, string ContentEncoding)
        {
            this.ResponseCode = ResponseCode;
            this.Content = Content;
            this.ContentEncoding = ContentEncoding;
        }

        public ResponseBuilder(int ResponseCode, string Content, string ContentEncoding)
        {
            this.ResponseCode = ResponseCode;
            this.Content = GetEncoder(ContentEncoding).GetBytes(Content);
            this.ContentEncoding = ContentEncoding;
        }

        public ResponseBuilder(int ResponseCode, byte[] Content, string ContentEncoding, string ContentType)
        {
            this.ResponseCode = ResponseCode;
            this.Content = Content;
            this.ContentEncoding = ContentEncoding;
            this.ContentType = ContentType;
        }

        public ResponseBuilder(int ResponseCode, string Content, string ContentEncoding, string ContentType)
        {
            this.ResponseCode = ResponseCode;
            this.Content = GetEncoder(ContentEncoding).GetBytes(Content);
            this.ContentEncoding = ContentEncoding;
            this.ContentType = ContentType;
        }

        public ResponseBuilder(int ResponseCode, byte[] Content, string ContentEncoding, string ContentType, Dictionary<string, string> Headers)
        {
            this.ResponseCode = ResponseCode;
            this.Content = Content;
            this.ContentEncoding = ContentEncoding;
            this.ContentType = ContentType;
            this.Headers = Headers;
        }

        public ResponseBuilder(int ResponseCode, string Content, string ContentEncoding, string ContentType, Dictionary<string, string> Headers)
        {
            this.ResponseCode = ResponseCode;
            this.Content = GetEncoder(ContentEncoding).GetBytes(Content);
            this.ContentEncoding = ContentEncoding;
            this.ContentType = ContentType;
            this.Headers = Headers;
        }

        public byte[] BuildResponse()
        {
            /*
             * string ResponseStr =
                        "HTTP/1.1 " + Response + "\r\n" +
                        "Date: " + DateTime.Now.ToString("r") + "\r\n" +
                        "Server: " + ServerString + "\r\n" +
                        "Content-Length: " + Page.Length + "\r\n" +
                        "Connection: close\r\n" +
                        "Content-Type: text/html; charset=iso-8859-1\r\n" +
                        "\r\n" +
                        Page;*/
            string HeadersStr =
                "HTTP/1.1 " + GetResponseCodeString(ResponseCode) + "\r\n" +
                "Date: " + DateTime.Now.ToString("r") + "\r\n" +
                "Content-Length: " + Content.Length + "\r\n" +
                "Content-Type: " + ContentType + "; charset=" + ContentEncoding + "\r\n" +
                "\r\n";

            byte[] Headers = Encoding.ASCII.GetBytes(HeadersStr);

            byte[] Response = new byte[Headers.Length + Content.Length];
            Headers.CopyTo(Response, 0);
            Content.CopyTo(Response, Headers.Length);

            return Response;
        }

        private Encoding GetEncoder(string Name)
        {
            foreach (EncodingInfo ei in Encoding.GetEncodings())
            {
                Encoding e = ei.GetEncoding();

                if (e.BodyName == Name)
                    return e;
            }

            return Encoding.ASCII;
        }

        public string GetResponseCodeString(int Code)
        {
            Dictionary<int, string> ResponseCodeTable = new Dictionary<int, string>();
            ResponseCodeTable.Add(100, "Continue");
            ResponseCodeTable.Add(101, "Switching Protocols");

            ResponseCodeTable.Add(200, "OK");
            ResponseCodeTable.Add(201, "Created");
            ResponseCodeTable.Add(202, "Accepted");
            ResponseCodeTable.Add(203, "Non-Authoritative Information");
            ResponseCodeTable.Add(204, "No Content");
            ResponseCodeTable.Add(205, "Reset Content");
            ResponseCodeTable.Add(206, "Partial Content");

            ResponseCodeTable.Add(300, "Multiple Choices");
            ResponseCodeTable.Add(301, "Moved Permanently");
            ResponseCodeTable.Add(302, "Found");
            ResponseCodeTable.Add(303, "See Other");
            ResponseCodeTable.Add(304, "Not Modified");
            ResponseCodeTable.Add(305, "Use Proxy");
            ResponseCodeTable.Add(307, "Temporary Redirect");

            ResponseCodeTable.Add(400, "Bad Request");
            ResponseCodeTable.Add(401, "Unauthorized");
            ResponseCodeTable.Add(402, "Payment Required");
            ResponseCodeTable.Add(403, "Forbidden");
            ResponseCodeTable.Add(404, "Not Found");
            ResponseCodeTable.Add(405, "Method Not Allowed");
            ResponseCodeTable.Add(406, "Not Acceptable");
            ResponseCodeTable.Add(407, "Proxy Authentication Required");
            ResponseCodeTable.Add(408, "Request Time-out");
            ResponseCodeTable.Add(409, "Conflict");
            ResponseCodeTable.Add(410, "Gone");
            ResponseCodeTable.Add(411, "Length Required");
            ResponseCodeTable.Add(412, "Precondition Failed");
            ResponseCodeTable.Add(413, "Request Entity Too Large");
            ResponseCodeTable.Add(414, "Request-URI Too Large");
            ResponseCodeTable.Add(415, "Unsupported Media Type");
            ResponseCodeTable.Add(416, "Request range not satisfiable");
            ResponseCodeTable.Add(417, "Expectation Failed");

            ResponseCodeTable.Add(500, "Internal Server Error");
            ResponseCodeTable.Add(501, "Not Implemented");
            ResponseCodeTable.Add(502, "Bad Gateway");
            ResponseCodeTable.Add(503, "Service Unavailable");
            ResponseCodeTable.Add(504, "Gateway Time-out");
            ResponseCodeTable.Add(505, "HTTP Version not supported");

            string ResponseName = null;
            if (ResponseCodeTable.TryGetValue(Code, out ResponseName))
                return string.Format("{0} {1}", Code, ResponseName);
            else
                return string.Format("{0} {0}", Code);
        }
    }
}
